package coms.dataaccess.hibernate;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import coms.dataaccess.ConferenceDAO;
import coms.dataaccess.ConferenceItemDAO;
import coms.dataaccess.DAOFactory;
import coms.dataaccess.FileItemDAO;
import coms.dataaccess.UserDao;
import coms.datatransfer.ConferenceDTO;
import coms.datatransfer.ConferenceItemDTO;
import coms.datatransfer.ConferenceItem_User;
import coms.datatransfer.FileItemDTO;
import coms.datatransfer.TransactionDTO;
import coms.datatransfer.UserDTO;
import coms.exception.HibernateAccessLayerException;
import coms.exception.RegistrationDateExpiredException;

public class ConferenceDAOImpl extends AbstractDAO implements ConferenceDAO{

	//private ConferenceItemDAO conferenceItemDAO= null;
	//private FileItemDAO fileItemDAO= null;
	//private UserDao userDAO = null;
	
	public ConferenceDAOImpl(){
		super();
	}
	
	/*public void initialize(){
		conferenceItemDAO = DAOFactory.getInstance().getConferenceItemDAO();
		userDAO = DAOFactory.getInstance().getUserDAO();
		fileItemDAO = DAOFactory.getInstance().getFileItemDAO();
	}*/
	
	@Override
	public Integer insertConference(ConferenceDTO conference) {
		//Logger.getLogger(getClass().getName()).log(Level.INFO, "Inserting File Item " + conference.getConferenceID());
		super.saveOrUpdate(conference);
		return conference.getConferenceID();
	}
	
	public void insertConferenceItem(ConferenceItemDTO conferenceItem, int conferenceID){
		//Logger.getLogger(getClass().getName()).log(Level.INFO, "Inserting File Item " + conferenceItem.getConferenceItemID());
		ConferenceDTO conference = findConferenceByID(conferenceID);
		List<ConferenceItemDTO> list = conference.getListOfConferenceItems();
		
		list.add(conferenceItem);
		conference.setListOfConferenceItems(list);
		
		super.saveOrUpdate(conference);
	}
	
	@Override
	public void insertFileItem(FileItemDTO fileItem){
		//fileItemDAO.insertFileItem(fileItem);
		super.saveOrUpdate(fileItem);
	}

	@Override
	public void insertFileItem(String conferenceItemID) {
		
	}
	
	@Override
	public ConferenceDTO findConferenceByID(String conferenceID) {
		//Logger.getLogger(getClass().getName()).log(Level.INFO, "Finding Conference" + conferenceID);
		ConferenceDTO conference = (ConferenceDTO) super.find(ConferenceDTO.class, conferenceID);
		return conference;
	}

	@Override
	public ConferenceItemDTO findConferenceItemByID(int conferenceItemID) {
		//Logger.getLogger(getClass().getName()).log(Level.INFO, "Finding Conference Item" + conferenceItemID);
		ConferenceItemDTO conferenceItem = (ConferenceItemDTO) super.find(ConferenceItemDTO.class, conferenceItemID);
		return conferenceItem;
	}

	@Override
	public FileItemDTO findFileItemByID(String fileItemID) {
		//Logger.getLogger(getClass().getName()).log(Level.INFO, "Finding File Item" + fileItemID);
		FileItemDTO fileItem = (FileItemDTO) super.find(FileItemDTO.class, fileItemID);
		return fileItem;
	}

	@Override
	public void updateConference(ConferenceDTO conference) {
		//Logger.getLogger(getClass().getName()).log(Level.INFO, "Updating Conference " + conference.getConferenceID());
        try {
            super.saveOrUpdate(conference);
            Logger.getLogger(getClass().getName()).log(Level.INFO, "Updating Conference items " + conference.getConferenceID());
            List<ConferenceItemDTO> conferenceItems = conference.getListOfConferenceItems();
            for(ConferenceItemDTO conferenceItem: conferenceItems){
            	updateConferenceItem(conferenceItem);
            }
            
        } catch (Throwable t) {
            throw new HibernateAccessLayerException(t.toString());
            
        }		
	}

	public void updateConferenceItem(ConferenceItemDTO conferenceItem) {
		try {
		    //Logger.getLogger(getClass().getName()).log(Level.INFO, "Updating order item " + conferenceItem.getConferenceItemID());
		    super.saveOrUpdate(conferenceItem);
		} catch (Throwable t) {
		    throw new HibernateAccessLayerException(t.toString());	            
		}
	}

	@Override
	public void deleteConference(int conferenceID) {
		ConferenceDTO conference = findConferenceByID(conferenceID);
		try {
            Logger.getLogger(getClass().getName()).log(Level.INFO, "Deleting order item " + conferenceID);
            super.delete(conference);
         } catch (Throwable t) {
            throw new HibernateAccessLayerException(t.toString());            
         }
	}
	
	@Override
	public ConferenceDTO findConferenceByID(int conferenceID) {
		//Logger.getLogger(getClass().getName()).log(Level.INFO, "Finding Conference" + conferenceID);
		ConferenceDTO conference = (ConferenceDTO) super.find(ConferenceDTO.class, new Integer(conferenceID));
		return conference;
	}


	@SuppressWarnings("unchecked")
	@Override
	public ArrayList<ConferenceDTO> findAllConferences() {
		ArrayList<ConferenceDTO> allConferences = (ArrayList<ConferenceDTO>)super.findAll(ConferenceDTO.class);
		return allConferences;
	}

	@Override
	public void deleteConferenceItem(int conferenceItemID) {
		
	}

	@Override
	public void registerParticipant(int conferenceItemID, int userID) throws RegistrationDateExpiredException {
		ConferenceItemDTO conferenceItem = findConferenceItemByID(conferenceItemID);
		//UserDTO userDTO = userDAO.findUserByID(userID);
		UserDTO userDTO = (UserDTO)super.find(UserDTO.class, userID);
		
		if(conferenceItem.getDeadlineForSubmission().after(new Date())){
			Set<ConferenceItem_User> participants = conferenceItem.getListOfParticipants();
			System.out.println(participants.size());
			ConferenceItem_User associated = new ConferenceItem_User();
			associated.setUserDTO(userDTO);
			associated.setStatus("Not Eligible");
			/*checkStatus(conferenceItemID, userID);
			
			associated.setStatus("Eligible");*/
			participants.add(associated);
			conferenceItem.setListOfParticipants(participants);
			updateConferenceItem(conferenceItem);
		} else {
			throw new RegistrationDateExpiredException("Sorry, Registration Date for this item has expired");
		}
	}
	
	public void makePayment(TransactionDTO transaction){
		super.saveOrUpdate(transaction);
		ConferenceItemDTO conferenceItemDTO = findConferenceItemByID(transaction.getConferenceItemID());
		//UserDTO userDTO = userDAO.findUserByID(transaction.getUserID());
		UserDTO userDTO = (UserDTO)super.find(UserDTO.class, transaction.getUserID());
		
		if(transaction.getPaidAmount() >= conferenceItemDTO.getItemFee()){
			Set<ConferenceItem_User> set = conferenceItemDTO.getListOfParticipants();
			
		}
	}
	
	@SuppressWarnings("unchecked")
	public List<Object[]> findRegisteredConferenceItems(int uID){	
		List<Object[]> list = (List<Object[]>) super.findAssociatedStatus(uID);
		//list.get(0).setStatus("Eligible");
		return list;
	}
	
	@SuppressWarnings("unchecked")
	public boolean checkStatus(ConferenceItemDTO conferenceItem, UserDTO userDTO){
		List<TransactionDTO> transaction = (List<TransactionDTO>) super.findTransaction(conferenceItem.getConferenceItemID(), userDTO.getUserID());
		boolean status = false;
		if(transaction != null && transaction.get(0).getPaidAmount()>=conferenceItem.getItemFee()){
			status = true;
		}else{
			status = true;
		}
		return status;
	}

	@Override
	public void changeStatus(int cID, int uID) {
		// TODO Auto-generated method stub
		
	}
}
